<template>
  <div class="generate-page">

    <div class="d-f" style="justify-content: space-between;width: 100%;height: 100%;">
      <scroll-view>
        <el-card class="box-card">
          <div slot="header" class="d-f a-i-c" style="justify-content: space-between">
            <div class="d-f a-i-c f-w-w">
              <div><span style="color: red;font-size: 20px;font-weight: bold;">*</span>页面中文名(必填)：
              </div>
              <el-input v-model="filedConfig.pageCnName" size="mini" style="width: 120px;"
                        placeholder="请填写页面名(中文、必填)"></el-input>

              <div class="ml-10"><span style="color: red;font-size: 20px;font-weight: bold;">*</span>页面英文名(必填、字母开头)：
              </div>
              <el-input v-model="filedConfig.pageEnName" size="mini" style="width: 180px;"
                        placeholder="请填写页面名(英文、必填、纯字母)"></el-input>

              <div class="ml-10"><span style="color: red;font-size: 20px;font-weight: bold;">*</span>主键(必填字段名、id)：</div>
              <el-input v-model="filedConfig.primaryKey" size="mini" style="width: 140px;"
                        placeholder="请填写主键(必填)"></el-input>
            </div>
            <div style="flex-shrink: 0;">
              <el-button style="" type="primary" size="mini" @click="add" plain>增加字段</el-button>
              <el-button style="" type="primary" size="mini" @click="publicConfigFix=true" plain>生成字段配置</el-button>
            </div>
          </div>
          <div class="">
            <div v-if="filedConfig.table.length">
              <draggable class="selectComs" :list="filedConfig.table" handle=".mover" :options="{ animation: 100}">
                <div v-for="(item,i) in filedConfig.table" :key="i">
                  <el-form :inline="true" :model="item" size="mini" class="demo-form-inline">
                    <el-form-item class="mover" style="cursor: move;">
                      <div
                        style="display: inline-block;color: #fff;font-size: 15px;width: 18px;height: 18px;text-align: center;line-height: 18px;vertical-align:middle;background: #4e81d5;border-radius: 50%;">
                        {{i+1}}
                      </div>
                    </el-form-item>
                    <el-form-item label="key">
                      <el-input v-model="item.prop" class="input-class" style="width: 128px;"  placeholder="字段key"></el-input>
                    </el-form-item>
                    <el-form-item label="字段名">
                      <el-input v-model="item.label" class="input-class" style="width: 108px;" placeholder="字段名"></el-input>
                    </el-form-item>
                    <el-form-item label="值">
                      <el-input v-model="item.value" class="input-class" placeholder="示例值"></el-input>
                    </el-form-item>
                    <el-form-item label="列宽">
                      <el-input v-model="item.width" class="input-class" style="width: 60px;"
                                placeholder="列宽度"></el-input>
                    </el-form-item>
                    <el-form-item label="对齐">
                      <el-select v-model="item.align" class="input-class" style="width: 60px;" placeholder="对齐方式">
                        <el-option label="左" value="left"></el-option>
                        <el-option label="中" value="center"></el-option>
                        <el-option label="右" value="right"></el-option>
                      </el-select>
                    </el-form-item>
                    <el-form-item label="slot">
                      <el-switch
                        class="ml-switch-mini"
                        @change="isSlotChange(item)"
                        v-model="item.isSlot">
                      </el-switch>
                    </el-form-item>
                    <el-form-item label="过滤器">
                      <el-select v-model="item.filter" @change="filterChange(item)" class="input-class"
                                 style="width: 120px;" placeholder="过滤器">
                        <el-option label="无" value=""></el-option>
                        <el-option label="日期时间(yyyy-MM-dd hh:mm:ss)" value="dateTime"></el-option>
                        <el-option label="日期(yyyy-MM-dd)" value="date"></el-option>
                        <el-option label="时间(hh:mm:ss)" value="time"></el-option>
                      </el-select>
                    </el-form-item>
                    <el-form-item label="显示">
                      <el-checkbox-group v-model="item.showArr" class="vue-checkbox">
                        <el-checkbox label="table">表格</el-checkbox>
                        <el-checkbox label="form">表单</el-checkbox>
                      </el-checkbox-group>
                    </el-form-item>
                    <el-form-item label="表单类型" v-if="item.showArr.includes('form')">
                      <el-select v-model="item.formConfig.type" class="input-class" style="width: 100px;"
                                 @change="changeFormConfigType(item)" placeholder="表单类型">
                        <el-option :label="item.name" :value="item.type" v-for="(item,i) in formTypeArr"
                                   :key="i"></el-option>
                      </el-select>
                    </el-form-item>
                    <el-form-item>
                      <el-button type="primary" size="mini" round plain @click="openFormConfigFix(item,i)">表单配置
                      </el-button>
                    </el-form-item>
                    <el-form-item>
                      <el-button type="danger" size="mini" round plain @click="deleteFiled(i)">移除</el-button>
                    </el-form-item>
                  </el-form>
                </div>
              </draggable>
            </div>
            <div v-else>
              <el-empty description="暂无字段，点击右上角增加字段"></el-empty>
            </div>

          </div>
        </el-card>

        <el-card class="box-card mt-15">
          <div slot="header" class="clearfix">
            <span>接口</span>
            <span class="tip">填写新增改查接口key或路径</span>
            <!--<el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button>-->
          </div>
          <div class="d-f mb-10">
            <div>
              弹窗：
              <el-checkbox v-model="filedConfig.add">新增</el-checkbox>
              <el-checkbox v-model="filedConfig.edit">编辑</el-checkbox>
              <el-checkbox v-model="filedConfig.delete">删除</el-checkbox>
            </div>
            <div class="ml-10">
              分页：
              <el-switch
                v-model="filedConfig.pagination">
              </el-switch>
            </div>
          </div>
          <div class="d-f a-i-c">
            <div class="d-f a-i-c mr-15">
              <div>获取列表接口：</div>
              <el-input v-model="apiConfig.listKey" size="mini" style="width: 180px;"
                        placeholder="请输入接口key或路径" maxlength="150"></el-input>
            </div>
            <div class="d-f a-i-c mr-15" v-if="filedConfig.add">
              <div>新增接口：</div>
              <el-input v-model="apiConfig.addKey" size="mini" style="width: 180px;"
                        placeholder="请输入接口key或路径" maxlength="150"></el-input>
            </div>
            <div class="d-f a-i-c mr-15" v-if="filedConfig.edit">
              <div>编辑接口：</div>
              <el-input v-model="apiConfig.editKey" size="mini" style="width: 180px;"
                        placeholder="请输入接口key或路径" maxlength="150"></el-input>
            </div>
            <div class="d-f a-i-c mr-15" v-if="filedConfig.delete">
              <div>删除接口：</div>
              <el-input v-model="apiConfig.deleteKey" size="mini" style="width: 180px;"
                        placeholder="请输入接口key或路径" maxlength="150"></el-input>
            </div>
          </div>
        </el-card>

        <el-card class="box-card mt-15">
          <div slot="header" class="clearfix">
            <span>预览效果</span>
            <!--<el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button>-->
          </div>
          <scroll-view>
            <div class="mb-10" slot="head">
              <el-button v-if="filedConfig.add" type="primary" size="mini" @click="dialogFormVisible=true">
                新增{{filedConfig.pageCnName}}
              </el-button>
            </div>
            <el-table
              class="ml-table"
              border
              height="100%"
              :data="tableData"
              style="width: 100%">
              <template v-for="(item,i) in filedConfig.table">
                <el-table-column
                  v-if="item.showArr.includes('table')"
                  :label="item.label"
                  :align="item.align"
                  :width="item.width">
                  <template slot-scope="{row,$index}">
                    <template v-if="item.filter === 'dateTime'">
                      {{ row[item.prop] | _formatDate("yyyy-MM-dd hh:mm:ss")}}
                    </template>
                    <template v-else-if="item.filter === 'date'">
                      {{ row[item.prop] | _formatDate("yyyy-MM-dd")}}
                    </template>
                    <template v-else-if="item.filter === 'time'">
                      {{ row[item.prop] | _formatDate("hh:mm:ss")}}
                    </template>
                    <template v-else>{{ row[item.prop]}}</template>
                  </template>
                </el-table-column>
              </template>
              <template v-if="filedConfig.table.length">
                <el-table-column
                  v-if="filedConfig.edit || filedConfig.delete"
                  width="150"
                  align="center"
                  label="操作">
                  <template slot-scope="{row}">
                    <el-button v-if="filedConfig.edit" type="primary" size="mini" @click="openDialogFormFix(row)" plain>
                      编辑
                    </el-button>
                    <el-button v-if="filedConfig.delete" type="danger" size="mini"
                               @click="deleteData(row[filedConfig.primaryKey])" plain>删除
                    </el-button>
                  </template>
                </el-table-column>
              </template>
            </el-table>
            <pagination
              v-if="filedConfig.pagination"
              slot="foot"
              :total="listQuery.total"
              :page.sync="listQuery.page"
              :limit.sync="listQuery.limit"
              @pagination="getList"
            />
          </scroll-view>
        </el-card>
        <div style="text-align: center;margin-top: 6px;color: #888;">
          codeepoch.com Copyright ©2022- CV攻城狮 版权所有
          <a class="text-color" href="https://beian.miit.gov.cn" target="_blank">闽ICP备19007976号-2</a>
        </div>
      </scroll-view>

      <el-card class="box-card ml-15 code-box" style="flex: 0 0 400px;height:100%;overflow: hidden;">
        <div slot="header" class="clearfix">
          <div style="float: left;">
            <span>生成代码</span>
            <el-button class="ml-10" size="mini" type="success" @click="generateCode">生成代码</el-button>
          </div>
          <el-button style="float: right; padding: 3px 0" type="text" @click="copyText">复制</el-button>
        </div>
        <!--代码-->
        <el-input v-if="realCode" type="textarea" class="code-textarea" v-model="realCode" autosize
                  style="width: 100%;height: 100%;overflow-y: scroll">
        </el-input>
        <el-empty v-else description="点击左上角生成代码"></el-empty>

      </el-card>
    </div>
    <!--</scroll-view>-->
    <!--配置全局字段-->
    <el-dialog title="生成字段配置" width="500px" :visible.sync="publicConfigFix" :close-on-click-modal="false"
               @close="closePublicConfigFix">
      <el-form ref="companyForm" label-width="auto" :model="publicConfig" size="mini">
        <el-form-item label="请求地址">
          <el-input v-model="publicConfig.url" placeholder="请输入请求地址" maxlength="200" autocomplete="off"
                    show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="请求返回的列表字段">
          <el-input v-model="publicConfig.resDataKey" placeholder="请输入请求返回的列表字段" maxlength="50" autocomplete="off"
                    show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="请求返回的提示字段">
          <el-input v-model="publicConfig.resMsgKey" placeholder="请输入请求返回的提示字段" maxlength="50" autocomplete="off"
                    show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="请求返回的状态字段">
          <el-input v-model="publicConfig.resStateKey" placeholder="请输入请求返回的状态字段" maxlength="50" autocomplete="off"
                    show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="请求返回的成功状态字段的值">
          <el-input v-model="publicConfig.resStateSuccessVal" placeholder="请输入请求返回的成功状态字段的值" maxlength="50"
                    autocomplete="off"
                    show-word-limit></el-input>
        </el-form-item>
        <el-form-item label="请求返回的分页总数字段">
          <el-input v-model="publicConfig.pageTotal" placeholder="请输入请求返回的分页总数字段" maxlength="50" autocomplete="off"
                    show-word-limit></el-input>
        </el-form-item>

      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="publicConfigFix = false" size="mini">取 消</el-button>
        <el-button type="primary" @click="surePublicConfig" size="mini">保 存</el-button>
      </div>
    </el-dialog>

    <!--配置选项-->
    <el-dialog
      :title="`【${filedConfig.table.length>0 && filedConfig.table[cIndex].label}】【${filedConfig.table.length>0 && filedConfig.table[cIndex].prop}】`+'表单配置'"
      width="500px" :visible.sync="formConfigFix" :close-on-click-modal="false"
      @close="closeFormConfig">
      <el-form ref="companyForm" label-width="auto" :model="formConfig" size="mini">
        <!--文本框-->
        <template v-if="formConfig.type === 'text'">
          <el-divider content-position="left">文本输入框</el-divider>
          <el-form-item label="占位文本：">
            <el-input v-model="formConfig.placeholder" placeholder="请输入文本输入框占位文本" maxlength="50" autocomplete="off"
                      clearable show-word-limit></el-input>
          </el-form-item>
          <el-form-item label="最大字数长度：">
            <el-input-number v-model="formConfig.maxlength" controls-position="right" :min="1"
                             :max="2000"></el-input-number>
          </el-form-item>
          <el-divider content-position="left">效果预览</el-divider>
          <el-form-item label="效果预览：">
            <el-input v-model="formConfig.value" type="text" :placeholder="formConfig.placeholder"
                      :maxlength="formConfig.maxlength" autocomplete="off" clearable show-word-limit></el-input>
          </el-form-item>
        </template>

        <!--文本域-->
        <template v-if="formConfig.type === 'textarea'">
          <el-divider content-position="left">文本域输入框</el-divider>
          <el-form-item label="占位文本">
            <el-input v-model="formConfig.placeholder" placeholder="请输入文本域输入框占位文本" maxlength="50" autocomplete="off"
                      clearable show-word-limit></el-input>
          </el-form-item>
          <el-form-item label="最大字数长度">
            <el-input-number v-model="formConfig.maxlength" controls-position="right" :min="1"
                             :max="2000"></el-input-number>
          </el-form-item>
          <el-form-item label="输入框行数">
            <el-input-number v-model="formConfig.rows" controls-position="right" :min="1" :max="50"></el-input-number>
          </el-form-item>

          <el-divider content-position="left">效果预览</el-divider>
          <el-form-item label="效果预览：">
            <el-input v-model="formConfig.value" type="textarea" :placeholder="formConfig.placeholder"
                      :maxlength="formConfig.maxlength" :rows="formConfig.rows" resize="both" autocomplete="off"
                      show-word-limit></el-input>
          </el-form-item>
        </template>

        <!--数字-->
        <template v-if="formConfig.type === 'inputNumber'">
          <el-divider content-position="left">数字输入框</el-divider>
          <el-form-item label="设置计数器允许的最小值">
            <el-input-number v-model="formConfig.min" controls-position="right" :min="0" :max="2000"></el-input-number>
          </el-form-item>
          <el-form-item label="设置计数器允许的最大值">
            <el-input-number v-model="formConfig.max" controls-position="right" :min="0"
                             :max="200000"></el-input-number>
          </el-form-item>
          <el-form-item label="数值精度(保留几位小数点)">
            <el-input-number v-model="formConfig.precision" controls-position="right" :min="0"
                             :max="6"></el-input-number>
          </el-form-item>
          <el-divider content-position="left">效果预览</el-divider>
          <el-form-item label="效果预览：">
            <el-input-number v-model="formConfig.value" controls-position="right" :precision="formConfig.precision"
                             :min="formConfig.min" :max="formConfig.max"></el-input-number>
          </el-form-item>
        </template>

        <!--单选框-->
        <template v-if="formConfig.type === 'radio' || formConfig.type === 'checkbox' || formConfig.type === 'select'">
          <el-divider v-if="formConfig.type === 'radio'" content-position="left">单选框</el-divider>
          <el-divider v-if="formConfig.type === 'checkbox'" content-position="left">复选框</el-divider>
          <el-divider v-if="formConfig.type === 'select'" content-position="left">下拉列表</el-divider>
          <el-form-item label="默认值">
            <el-select v-model="formConfig.default" :multiple="formConfig.type === 'checkbox'" placeholder="请选择默认值">
              <el-option
                v-for="item in formConfig.options"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="占位文本">
            <el-input v-model="formConfig.placeholder" placeholder="请输入文本域输入框占位文本" maxlength="50" autocomplete="off"
                      clearable show-word-limit></el-input>
          </el-form-item>
          <div>
            配置选项:
            <el-button type="primary"
                       @click="formConfig.options.push({label:'选项'+formConfig.options.length,value:'val'+formConfig.options.length})"
                       size="mini">新增选项
            </el-button>
          </div>

          <div class="pt-6">
            <div class="d-f a-i-c mt-6" v-for="(item,i) in formConfig.options" :key="i">
              <span>【{{i+1}}】</span>
              选项名：
              <el-input
                class="mr-20"
                placeholder="请输入选项名" maxlength="30" autocomplete="off" show-word-limit
                size="mini" style="width: 130px;"
                v-model="item.label">
              </el-input>
              选项值：
              <el-input
                placeholder="请输入选项值" maxlength="30" autocomplete="off" show-word-limit
                size="mini" style="width: 140px;"
                v-model="item.value">
              </el-input>
              <span class="el-icon-delete ml-6" style="cursor: pointer;" @click="formConfig.options.splice(i,1)"></span>
            </div>
          </div>

          <el-divider content-position="left">效果预览</el-divider>
          <el-form-item label="效果预览：">
            <el-radio-group v-if="formConfig.type === 'radio'" :value="formConfig.default">
              <el-radio :label="item.value" v-for="(item,i) in formConfig.options" :key="i">{{item.label}}</el-radio>
            </el-radio-group>
            <el-checkbox-group v-if="formConfig.type === 'checkbox'" :value="formConfig.default">
              <el-checkbox :label="item.value" v-for="(item,i) in formConfig.options" :key="i">{{item.label}}
              </el-checkbox>
            </el-checkbox-group>
            <el-select v-if="formConfig.type === 'select'" :value="formConfig.default"
                       :placeholder="formConfig.placeholder">
              <el-option
                v-for="item in formConfig.options"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
        </template>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="formConfigFix = false" size="mini">取 消</el-button>
        <el-button type="primary" @click="saveFormConfig(formConfig)" size="mini">保 存</el-button>
      </div>
    </el-dialog>

    <!--新增/编辑主项目-->
    <el-dialog :title="supplier_id?'编辑'+filedConfig.pageCnName:'新增'+filedConfig.pageCnName" width="600px"
               :visible.sync="dialogFormVisible"
               :close-on-click-modal="false" @close="closeCompanyFix">
      <el-form ref="companyForm" label-width="auto" :model="companyForm" :rules="companyFormRules"
               size="mini">

        <template v-for="(item,i) in filedConfig.table">
          <el-form-item v-if="item.showArr.includes('form')" :label="item.label" :key="i">
            <el-input v-if="item.formConfig.type === 'text'" v-model="companyForm[item.prop]"
                      :placeholder="item.formConfig.placeholder" :maxlength="item.formConfig.maxlength"
                      autocomplete="off" clearable show-word-limit></el-input>
            <el-input v-if="item.formConfig.type === 'textarea'" v-model="companyForm[item.prop]" type="textarea"
                      :placeholder="item.formConfig.placeholder"
                      :maxlength="item.formConfig.maxlength" :rows="item.formConfig.rows" resize="both"
                      autocomplete="off"
                      show-word-limit></el-input>
            <el-input-number v-if="item.formConfig.type === 'inputNumber'" v-model="companyForm[item.prop]"
                             controls-position="right" :precision="item.formConfig.precision"
                             :min="item.formConfig.min" :max="item.formConfig.max"></el-input-number>

            <el-radio-group v-if="item.formConfig.type === 'radio'" v-model="companyForm[item.prop]">
              <el-radio :label="v.value" v-for="(v,i) in item.formConfig.options" :key="i">{{v.label}}</el-radio>
            </el-radio-group>

            <el-checkbox-group v-if="item.formConfig.type === 'checkbox'" v-model="companyForm[item.prop]">
              <el-checkbox :label="v.value" v-for="(v,i) in formConfig.options" :key="i">{{v.label}}</el-checkbox>
            </el-checkbox-group>

            <el-select v-if="item.formConfig.type === 'select'" v-model="companyForm[item.prop]"
                       :placeholder="item.formConfig.placeholder">
              <el-option
                v-for="(v,i) in item.formConfig.options"
                :key="i"
                :label="v.label"
                :value="v.value">
              </el-option>
            </el-select>
          </el-form-item>
        </template>

      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false" size="mini">取 消</el-button>
        <el-button type="primary" @click="sureCompany" size="mini">确 定</el-button>
      </div>
    </el-dialog>

    <!--<div class="generate-btn" @click="generateCode">生成代码</div>-->

  </div>
</template>

<script>
  import draggable from "vuedraggable"

  export default {
    components: {
      draggable
    },
    name: "generateVue",
    data() {
      return {
        // 全局配置
        publicConfig: {
          url: "http://192.168.1.78:19611",//请求地址
          resDataKey: "data",//响应的列表字段
          resStateKey: "rCode",//响应的状态字段
          resStateSuccessVal: "2",//响应的状态字段的值
          resMsgKey: "rMsg",//响应的提示字段
          pageTotal: "pageInfo.total"//响应的状态字段的值
        },
        publicConfigFix: false,
        // 表单配置
        cIndex: 0,// 当前编辑项所在的索引
        formConfigFix: false,
        formConfig: {
          type: "text",
          value: "",
          default: "",//默认值
          placeholder: "请输入",//占位文本 [text,textarea,inputNumber]
          maxlength: "150",// 最大字数 [text,textarea]
          options: [ // 选项 [radio,checkbox,select]
            {
              label: "",
              value: ""
            }
          ],
          rows: 3,//行数 [textarea]
          min: 0,//设置计数器允许的最小值 [inputNumber]
          max: 100000,//设置计数器允许的最大值 [inputNumber]
          precision: 0//数值精度 [inputNumber]
        },
        formTypeArr: [
          {
            type: "text",
            name: "普通文本"
          },
          {
            type: "inputNumber",
            name: "数字"
          },
          {
            type: "textarea",
            name: "文本域"
          },
          {
            type: "radio",
            name: "单选框"
          },
          {
            type: "checkbox",
            name: "复选框"
          },
          {
            type: "select",
            name: "下拉列表"
          },
          {
            type: "upload",
            name: "图片上传"
          },
          {
            type: "selectMap",
            name: "选择地址"
          }
        ],

        dialogFormVisible: false,
        supplier_id: "",
        companyFormRules: {
          supplier_name: [
            {
              required: true,
              message: "请输入真实的项目名称，4-30字符之内",
              trigger: "blur"
            },
            {
              min: 4,
              max: 30,
              message: "项目名称长度在 4 到 30 个字符",
              trigger: "blur"
            }
          ],
          supplier_name_short: [
            {
              required: true,
              message: "请输入项目简称，简短已记",
              trigger: "blur"
            },
            {
              min: 2,
              max: 12,
              message: "长度在 2 到 12 个字符",
              trigger: "blur"
            }
          ]
        },
        tempUpUrl: "",//临时上传路径
        companyForm: {},
        tableData: [],
        listQuery: {
          total: 0,
          page: 1,
          limit: 10
        },
        filedConfig: {
          // pageEnName: "houseManage",
          // pageEnNameHump: "HouseManage",// 大驼峰
          // pageCnName: "房源",
          // primaryKey: "house_id",//主键
          pageEnName: "",
          pageEnNameHump: "",// 大驼峰
          pageCnName: "",
          primaryKey: "",//主键
          add: true,//新增按钮
          edit: true,//编辑按钮
          delete: true,//删除按钮
          table: [],
          form: {},
          pagination: true// 是否开启分页
        },
        apiConfig: {
          listKey: "",
          addKey: "",
          editKey: "",
          deleteKey: ""
        },
        formOptions: {},//储存表单的选项对象
        filterCodeArr: "",//filterCode
        realCode: ""//生成的代码
      }
    },
    watch: {
      "filedConfig.table": {
        handler() {
          this.tableData = []
          this.getTable()
        },
        deep: true
      },
      "filedConfig.pageEnName"(val) {
        if (val) {
          this.filedConfig.pageEnNameHump = this.toOneUpperCase(val)
        }
      }
    },
    created() {
      // this.getList()
      let publicConfig = this._storage.get("publicConfig")
      if (publicConfig) {
        this.publicConfig = this._storage.get("publicConfig")
      } else {
        this._storage.set("publicConfig", this.publicConfig)
      }
    },
    methods: {
      copyText(){
        try {
          navigator.clipboard.writeText(this.realCode).then((res)=>{
            this.$notify.success({
              title:"提示",
              message:"复制成功",
              position: 'bottom-right',
              offset: 200
            })
          }).catch(()=>{
            this.$notify.error({
              title:"提示",
              message:"复制失败，请重试或手动复制代码",
              position: 'bottom-right',
              offset: 200
            })
          })
        }catch (e) {
          console.log("e",e)
          this.$notify.error({
            title:"提示",
            message:"该浏览器不支持自动复制，请手动复制代码",
            position: 'bottom-right',
            offset: 200
          })
        }
      },
      openFormConfigFix(item, i) {
        this.cIndex = i
        this.formConfig = JSON.parse(JSON.stringify(item.formConfig))
        this.formConfigFix = true
      },
      changeFormConfigType(data) {
        if (data.formConfig.type === "inputNumber") {
          data.formConfig.default = 0
          data.formConfig.value = 0
        } else if (data.formConfig.type === "checkbox") {
          data.formConfig.default = []
        } else {
          data.formConfig.default = ""
          data.formConfig.value = ""
        }
      },
      saveFormConfig(config) {
        this.filedConfig.table[this.cIndex].formConfig = JSON.parse(JSON.stringify(config))
        this.formConfigFix = false
      },
      closeFormConfig() {

      },
      closePublicConfigFix() {
        this.publicConfig = this._storage.get("publicConfig")
      },
      surePublicConfig() {
        this._storage.set("publicConfig", this.publicConfig)
        this.publicConfigFix = false
      },
      filterChange(data) {
        data.isSlot = !!data.filter
      },
      isSlotChange(data) {
        if (!data.isSlot) {
          data.filter = ""
        }
      },
      toOneUpperCase(str = "") {
        // 首字母大写
        if (str) {
          return str.charAt(0)
            .toUpperCase() + str.slice(1)
        } else {
          return ""
        }
      },
      searchList() {
        this.listQuery.total = 0
        this.listQuery.page = 1
        this.getList()
      },
      getList() {
        this.$post(this.apiConfig.listKey, {
          page: this.listQuery.page,
          limit: this.listQuery.limit
        })
          .then((res) => {
            if (res[this.publicConfig.resStateKey] === this.publicConfig.resStateSuccessVal) {
              this.tableData = res[this.publicConfig.resDataKey] || []
              this.listQuery.total = res[this.publicConfig.pageTotal] || 0
            } else {
              this.$message.error(`获取${this.filedConfig.pageCnName}数据失败，${res[this.publicConfig.resMsgKey]}`)
            }
          })
      },
      closeCompanyFix() {
        // 弹窗内容重置
        this.supplier_id = ""
        this.companyForm = this.filedConfig.form
      },
      openDialogFormFix(item) {
        this.supplier_id = item[this.filedConfig.primaryKey]
        this.companyForm = JSON.parse(JSON.stringify(item))
        this.dialogFormVisible = true
      },
      sureCompany() {
        // 主项目编辑
        this.$refs.companyForm.validate((valid) => {
          if (valid) {
            if (!this.supplier_id) {
              // 新增
              let sendData = {
                ...this.companyForm
              }
              this.$post(this.apiConfig.addKey, sendData)
                .then((res) => {
                  if (res[this.publicConfig.resStateKey] === this.publicConfig.resStateSuccessVal) {
                    this.$message.success(`新增${this.filedConfig.pageCnName}成功`)
                    this.getList()
                    this.dialogFormVisible = false
                  } else {
                    this.$message.error(`新增${this.filedConfig.pageCnName}，失败${res[this.publicConfig.resMsgKey]}`)
                  }
                })
            } else {
              // 编辑
              let sendData = {
                ...this.companyForm,
                [this.filedConfig.primaryKey]: this.supplier_id
              }
              this.$post(this.apiConfig.editKey, sendData)
                .then((res) => {
                  if (res[this.publicConfig.resStateKey] === this.publicConfig.resStateSuccessVal) {
                    this.$message.success(`编辑${this.filedConfig.pageCnName}成功`)
                    this.getList()
                    this.dialogFormVisible = false
                  } else {
                    this.$message.error(`编辑${this.filedConfig.pageCnName}，失败${res[this.publicConfig.resMsgKey]}`)
                  }
                })
            }
          }
        })
      },
      deleteData(id) {
        this.$confirm(`是否确认删除？`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            this.$post(this.apiConfig.deleteKey, { [this.filedConfig.primaryKey]: id })
              .then((res) => {
                if (res[this.publicConfig.resStateKey] === this.publicConfig.resStateSuccessVal) {
                  this.$message.success(`删除${this.filedConfig.pageCnName}成功`)
                  this.getList()
                } else {
                  this.$message.error(`删除${this.filedConfig.pageCnName}，失败${res[this.publicConfig.resMsgKey]}`)
                }
              })
          })

      },
      getTable() {
        let obj = {}
        let formObj = {}
        this.filedConfig.table.forEach((v) => {
          if (v.showArr.includes("table")) {
            obj[v.prop] = v.value
          }
          if (v.showArr.includes("form")) {
            if (v.formConfig.type === "text") {
              formObj[v.prop] = ""
            } else if (v.formConfig.type === "textarea") {
              formObj[v.prop] = ""
            } else if (v.formConfig.type === "inputNumber") {
              formObj[v.prop] = 0
            } else if (v.formConfig.type === "radio") {
              formObj[v.prop] = v.formConfig.default || ""
            } else if (v.formConfig.type === "checkbox") {
              formObj[v.prop] = v.formConfig.default || []
            } else if (v.formConfig.type === "select") {
              formObj[v.prop] = v.formConfig.default || ""
            } else {
              formObj[v.prop] = ""
            }

          }
        })
        if (Object.keys(obj).length > 0) {
          this.tableData.push(obj)
        }
        this.filedConfig.form = formObj
        this.companyForm = formObj
      },
      add() {
        if (!this.filedConfig.pageCnName) {
          this.$message.error("请先填写页面中文名")
          return false
        }
        if (!this.filedConfig.pageEnName) {
          this.$message.error("请先填写页面英文名")
          return false
        }
        if (!this.filedConfig.primaryKey) {
          this.$message.error("请先填写主键")
          return false
        }
        this.filedConfig.table.push({
          prop: `key${this.filedConfig.table.length}`,
          label: `字段名${this.filedConfig.table.length}`,
          width: "auto",
          value: `示例值${this.filedConfig.table.length}`,
          align: "center",//可选 左、中、右
          isSlot: false,//是否 自定义列模板
          showArr: ["table", "form"],//
          filter: "",// 可选 时间（yyyy）
          formConfig: {
            type: "text",
            default: "",// 默认值
            value: "",// 效果展示时使用
            placeholder: "请输入",//占位文本 [text,textarea,inputNumber]
            maxlength: "150",// 最大字数 [text,textarea]
            options: [],
            rows: 3,//行数 [textarea]
            min: 0,//设置计数器允许的最小值 [inputNumber]
            max: 100000,//设置计数器允许的最大值 [inputNumber]
            precision: 0//数值精度 [inputNumber]
          }// 表单配置
        })
      },
      deleteFiled(i) {
        this.filedConfig.table.splice(i, 1)
      },
      generateCode() {
        if (!this.filedConfig.pageCnName) {
          this.$message.error("请先填写页面中文名")
          return false
        }
        if (!this.filedConfig.pageEnName) {
          this.$message.error("请先填写页面英文名")
          return false
        }
        if (!this.filedConfig.primaryKey) {
          this.$message.error("请先填写主键")
          return false
        }
        let htmlCode = this.generateHtmlCode()
        let scriptCode = this.generateScriptCode()

        this.realCode = `${htmlCode}

        ${scriptCode}`
        this.$message.success("生成成功")
      },
      generateHtmlCode() {
        // 生成html代码
        let html = ""
        let elTableColumnArr = []
        let elFormItemArr = []
        this.formOptions = {}
        this.filterCodeArr = []
        this.filedConfig.table.forEach((v, i) => {
          let filedObj = this.filedConfig.table[i]

          if (v.showArr.includes("table")) {
            let tableItem = ""
            if (filedObj.formConfig.type === "radio" || filedObj.formConfig.type === "checkbox" || filedObj.formConfig.type === "select") {
              tableItem = `<el-table-column
          label="${filedObj.label}"
          align="${filedObj.align}"
          width="${filedObj.width}">
          <template slot-scope="{row,$index}">
            {{ row.${filedObj.prop} | ${filedObj.prop}Filter(formOptions.${filedObj.prop}Options)}}
          </template>
        </el-table-column>`
              this.filterCodeArr.push(`${filedObj.prop}Filter(val,options=[]){
                let [obj] = options.filter(item=>item.value === val);
                return obj && obj.label?obj.label:val;
              },`)
            } else {
              if (filedObj.isSlot) {
                let tempCode = `{{ row.${filedObj.prop} }}`
                if (filedObj.filter === "dateTime") {
                  tempCode = `{{ row.${filedObj.prop} | _formatDate("yyyy-MM-dd hh:mm:ss")}}`
                } else if (filedObj.filter === "date") {
                  tempCode = `{{ row.${filedObj.prop} | _formatDate("yyyy-MM-dd")}}`
                } else if (filedObj.filter === "time") {
                  tempCode = `{{ row.${filedObj.prop} | _formatDate("hh:mm:ss")}}`
                }
                tableItem = `<el-table-column
          label="${filedObj.label}"
          align="${filedObj.align}"
          width="${filedObj.width}">
          <template slot-scope="{row,$index}">
            ${tempCode}
          </template>
        </el-table-column>`
              } else {
                tableItem = `<el-table-column
          prop="${filedObj.prop}"
          label="${filedObj.label}"
          align="${filedObj.align}"
          width="${filedObj.width}">
        </el-table-column>`
              }
            }

            elTableColumnArr.push(tableItem)
          }
          if (v.showArr.includes("form")) {
            let formItem = ""
            if (v.formConfig.type === "text") {
              formItem = `<el-form-item label="${filedObj.label}">
          <el-input v-model="${this.filedConfig.pageEnName}Form.${filedObj.prop}" placeholder="${v.formConfig.placeholder}" maxlength="${v.formConfig.maxlength}" autocomplete="off" clearable show-word-limit></el-input>
        </el-form-item>
            `
            } else if (v.formConfig.type === "textarea") {
              formItem = `<el-form-item label="${filedObj.label}">
          <el-input v-model="${this.filedConfig.pageEnName}Form.${filedObj.prop}" type="textarea"
                       placeholder="${v.formConfig.placeholder}" maxlength="${v.formConfig.maxlength}" :rows="${v.formConfig.rows}" resize="both"
                      autocomplete="off"
                      show-word-limit></el-input>
        </el-form-item>
            `

            } else if (v.formConfig.type === "inputNumber") {
              formItem = `<el-form-item label="${filedObj.label}">
          <el-input-number v-model="${this.filedConfig.pageEnName}Form.${filedObj.prop}"
                             controls-position="right" :precision="${v.formConfig.precision}"
                             :min="${v.formConfig.min}" :max="${v.formConfig.max}"></el-input-number>
        </el-form-item>
            `
            } else if (v.formConfig.type === "radio") {
              formItem = `<el-form-item label="${filedObj.label}">
          <el-radio-group v-model="${this.filedConfig.pageEnName}Form.${filedObj.prop}">
              <el-radio :label="v.value" v-for="(v,i) in formOptions.${filedObj.prop}Options" :key="i">{{v.label}}</el-radio>
            </el-radio-group>
        </el-form-item>
            `
              this.formOptions[`${filedObj.prop}Options`] = v.formConfig.options
            } else if (v.formConfig.type === "checkbox") {
              formItem = `<el-form-item label="${filedObj.label}">
          <el-checkbox-group v-model="${this.filedConfig.pageEnName}Form.${filedObj.prop}">
              <el-checkbox :label="v.value" v-for="(v,i) in formOptions.${filedObj.prop}Options" :key="i">{{v.label}}</el-checkbox>
            </el-checkbox-group>
        </el-form-item>
            `
              this.formOptions[`${filedObj.prop}Options`] = v.formConfig.options
            } else if (v.formConfig.type === "select") {
              formItem = `<el-form-item label="${filedObj.label}">
          <el-select v-model="${this.filedConfig.pageEnName}Form.${filedObj.prop}"
                       placeholder="${v.formConfig.placeholder}">
              <el-option
                v-for="(v,i) in formOptions.${filedObj.prop}Options"
                :key="i"
                :label="v.label"
                :value="v.value">
              </el-option>
            </el-select>
        </el-form-item>
            `
              this.formOptions[`${filedObj.prop}Options`] = v.formConfig.options
            } else {
              formItem = `<el-form-item label="${filedObj.label}">
          <el-input v-model="${this.filedConfig.pageEnName}Form.${filedObj.prop}" placeholder="${v.formConfig.placeholder}" maxlength="${v.formConfig.maxlength}" autocomplete="off" clearable show-word-limit></el-input>
        </el-form-item>
            `
            }

            elFormItemArr.push(formItem)
          }

        })

        if (this.filedConfig.edit || this.filedConfig.delete) {
          let editBtn = this.filedConfig.edit ? `<el-button type="primary" size="mini" @click="open${this.filedConfig.pageEnNameHump}Fix(row)" plain>编辑
            </el-button>` : ""
          let delBtn = this.filedConfig.delete ? `<el-button type="danger" size="mini" @click="delete${this.filedConfig.pageEnNameHump}(row.${this.filedConfig.primaryKey})" plain>删除
            </el-button>` : ""
          elTableColumnArr.push(`<el-table-column
          width="150"
          align="center"
          label="操作">
          <template slot-scope="{row}">
            ${editBtn}
            ${delBtn}
          </template>
        </el-table-column>`)
        }

        let headCode = this.filedConfig.add ? `<div class="mb-10" slot="head">
        <el-button type="primary" size="small" @click="${this.filedConfig.pageEnName}Fix=true">新增${this.filedConfig.pageCnName}</el-button>
      </div>` : ""

        let pagination = this.filedConfig.pagination ? `<\!--分页-->
        <pagination
              slot="foot"
              :total="listQuery.total"
              :page.sync="listQuery.page"
              :limit.sync="listQuery.limit"
              @pagination="get${this.filedConfig.pageEnNameHump}List"
            />` : ""

        let fixCode = this.filedConfig.add || this.filedConfig.edit ? `
        <\!-- 新增\/ 编辑${this.filedConfig.pageCnName}-->
    <el-dialog :title="${this.filedConfig.primaryKey}?'编辑${this.filedConfig.pageCnName}':'新增${this.filedConfig.pageCnName}'" width="600px" :visible.sync="${this.filedConfig.pageEnName}Fix"
               :close-on-click-modal="false" @close="close${this.filedConfig.pageEnNameHump}Fix">
      <el-form ref="${this.filedConfig.pageEnName}Form" label-width="auto" :model="${this.filedConfig.pageEnName}Form" size="small">
        ${elFormItemArr.join("\n         \n")}
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="${this.filedConfig.pageEnName}Fix = false" size="small">取 消</el-button>
        <el-button type="primary" @click="sure${this.filedConfig.pageEnNameHump}" size="small">确 定</el-button>
      </div>
    </el-dialog>
        ` : ""

        html = `<template>
    <div>
        <scroll-view>
            <\!-- 筛选栏 -->
            ${headCode}
            <\!-- ${this.filedConfig.pageCnName}表格列表-->
            <el-table
                class="ml-table"
                border
                height="100%"
                :data="${this.filedConfig.pageEnName}Data"
                style="width: 100%">
                    ${elTableColumnArr.join("\n         ")}
            </el-table>
            ${pagination}
        </scroll-view>
        ${fixCode}
    </div>
</template>`
        return html
      },
      generateScriptCode() {
        // 生成script代码
        let script = ""
        let pagination = this.filedConfig.pagination ? "listQuery:{\n" +
          "          total:0,\n" +
          "          page:1,\n" +
          "          limit:10,\n" +
          "        },// 分页" : ""

        let deleteMethod = this.filedConfig.delete ? `delete${this.filedConfig.pageEnNameHump}(id) {
        // 删除 ${this.filedConfig.pageCnName}
        this.$confirm("是否确认删除?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(() => {
          this.$post("${this.apiConfig.deleteKey}",{ ${this.filedConfig.primaryKey}: id })
            .then((res) => {
               if (res.${this.publicConfig.resStateKey} === "${this.publicConfig.resStateSuccessVal}") {
                this.$message.success("删除${this.filedConfig.pageCnName}成功");
                this.get${this.filedConfig.pageEnNameHump}List();
              } else {
                this.$message.error("删除${this.filedConfig.pageCnName}失败," + res.${this.publicConfig.resMsgKey});
              }
            })
        }).catch((e)=>{
          console.log(e);
        })
      },` : ""

        let openFixMethod = this.filedConfig.edit ? `open${this.filedConfig.pageEnNameHump}Fix(item) {
        // 打开编辑${this.filedConfig.pageCnName}弹窗
        this.${this.filedConfig.primaryKey} = item.${this.filedConfig.primaryKey};
        this.${this.filedConfig.pageEnName}Form = JSON.parse(JSON.stringify(item));
        this.${this.filedConfig.pageEnName}Fix = true;
      },` : ""
        let editMethod = ""
        let fixData = ""
        let formData = ""
        if (this.filedConfig.add || this.filedConfig.edit) {
          fixData = `${this.filedConfig.pageEnName}Fix:false,// 是否显示${this.filedConfig.pageCnName}弹窗`
          formData = `${this.filedConfig.pageEnName}Form:${JSON.stringify(this.filedConfig.form, null, 2)},// ${this.filedConfig.pageCnName}弹窗数据`
          editMethod = `
        ${openFixMethod}
      sure${this.filedConfig.pageEnNameHump}() {
        // 新增/编辑${this.filedConfig.pageCnName}
        this.$refs.${this.filedConfig.pageEnName}Form.validate((valid) => {
          if (valid) {
            if (!this.${this.filedConfig.primaryKey}) {
              // 新增
              let sendData = {
                ...this.${this.filedConfig.pageEnName}Form
              }
              this.$post("${this.apiConfig.addKey}",sendData)
                .then((res) => {
                  if (res.${this.publicConfig.resStateKey} === "${this.publicConfig.resStateSuccessVal}") {
                    this.$message.success("新增${this.filedConfig.pageCnName}成功");
                    this.get${this.filedConfig.pageEnNameHump}List();
                    this.${this.filedConfig.pageEnName}Fix = false;
                  } else {
                    this.$message.error("新增${this.filedConfig.pageCnName}失败，" + res.${this.publicConfig.resMsgKey});
                  }
                })
            } else {
              // 编辑
              let sendData = {
                ...this.${this.filedConfig.pageEnName}Form,
                ${this.filedConfig.primaryKey}: this.${this.filedConfig.primaryKey}
              }
              this.$post("${this.apiConfig.editKey}",sendData)
                .then((res) => {
                  if (res.${this.publicConfig.resStateKey} === "${this.publicConfig.resStateSuccessVal}") {
                    this.$message.success("编辑${this.filedConfig.pageCnName}成功");
                    this.get${this.filedConfig.pageEnNameHump}List();
                    this.${this.filedConfig.pageEnName}Fix = false;
                  } else {
                    this.$message.error("编辑${this.filedConfig.pageCnName}失败，" + res.${this.publicConfig.resMsgKey});
                  }
                })
            }
          }
        })
      },
      close${this.filedConfig.pageEnNameHump}Fix() {
        // 关闭${this.filedConfig.pageCnName}弹窗 且 内容重置
        this.${this.filedConfig.primaryKey} = ""
        this.${this.filedConfig.pageEnName}Form = ${JSON.stringify(this.filedConfig.form, null, 2)}
        },`
        }
        let formOptions = `formOptions:${JSON.stringify(this.formOptions, null, 2)},`
        script = `
<script>
export default {
  name: "${this.filedConfig.pageEnNameHump}",
  components:{},
  data() {
    return {
      ${this.filedConfig.pageEnName}Data:[],//${this.filedConfig.pageCnName} 表格数据
      ${pagination}
      ${this.filedConfig.primaryKey}:"",// ${this.filedConfig.pageCnName} id
      ${fixData}
      ${formData}
      ${formOptions}
    }
  },
  filters:{
    ${this.filterCodeArr.join("\n         ")}
  },
  watch:{},
  computed:{},
  created(){
    this.get${this.filedConfig.pageEnNameHump}List();
  },
  mounted(){},
  methods:{
    get${this.filedConfig.pageEnNameHump}List(){
    // 获取 ${this.filedConfig.pageCnName} 表格数据
      this.$post("${this.apiConfig.listKey}",${this.filedConfig.pagination ? "{\n          page: this.listQuery.page,\n          limit: this.listQuery.limit\n        }" : JSON.stringify({})}).then((res) => {
          if (res.${this.publicConfig.resStateKey} === "${this.publicConfig.resStateSuccessVal}") {
            this.${this.filedConfig.pageEnName}Data = res.${this.publicConfig.resDataKey} || [];
            this.listQuery.total = res.${this.publicConfig.pageTotal};
          } else {
            this.$message.error("获取数据失败," + res.${this.publicConfig.resMsgKey});
          }
        })
    },
    ${editMethod}
    ${deleteMethod}
  },
}
<\/script>
        `
        return `${script}`
      }
    }
  }
</script>

<style lang="scss" scoped>
  .box-card {
    &::v-deep {
      .el-card__header {
        padding: 14px 15px;
      }

      .el-card__body {
        padding: 10px 20px;
      }
    }
  }

  .generate-page {
    position: relative;
    width: 100%;
    height: 100%;
    padding: 20px;
    overflow: hidden;
    /*background: #ffffff*/
    &::v-deep {
      .el-form-item--mini.el-form-item {
        margin-bottom: 10px;

        .el-form-item__label {
          padding-right: 6px;
        }
      }

      .code-box .el-card__body {
        padding: 0;
        height: calc(100% - 60px);
        overflow: hidden;

        .code-textarea {

          .el-textarea__inner {
            overflow: hidden;
            font-size: 13px;
            line-height: 1.3;
            color: #444444;
            font-family: system-ui;
            min-height: 100%;
            border: none;
          }
        }
      }
    }
  }

  .tip {
    font-size: 12px;
    margin-left: 15px;
    color: #888;
  }

  .vue-checkbox {
    .el-checkbox {
      margin-right: 10px;
    }
  }

  .tools-area {
    background: #ffffff;
    padding: 10px 10px 0;
    border-radius: 6px;
  }

  .generate-btn {
    position: fixed;
    bottom: 30px;
    left: 0;
    right: 0;
    margin: auto;
    width: 70px;
    height: 70px;
    line-height: 70px;
    text-align: center;
    background: #ffffff;
    border-radius: 50%;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
    cursor: pointer;
    z-index: 22;

    &:hover {
      background: $primary;
      color: #fff;
    }
  }

  .input-class {
    width: 80px;
  }
</style>
